package main

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"server/base"

	"github.com/cheggaaa/pb/v3"
)

// 进度条
type WriteCounter struct {
	Bar *pb.ProgressBar
}

func (wc *WriteCounter) Write(p []byte) (int, error) {
	n := len(p)
	wc.Bar.Add(n)
	return n, nil
}

func CopyFile(src, dst string) error {
	srcstat, err := os.Stat(src)
	if err != nil {
		return err
	}
	if !srcstat.Mode().IsRegular() {
		return errors.New("来源文件不是正规文件")
	}
	//dststat, err := os.Stat(t.Dst)
	//if err != nil {
	//	return err
	//}
	//if !dststat.IsDir() {
	//	return errors.New("目标路径必须是目录")
	//}
	src = base.CleanPath(src)
	_, filename := path.Split(src)
	dstfile := filepath.Join(dst, filename)
	srcf, err := os.Open(src)
	if err != nil {
		return err
	}
	srcst, err := srcf.Stat()
	if err != nil {
		return err
	}
	w := &WriteCounter{
		Bar: pb.Full.New(int(srcst.Size())),
	}
	r := io.TeeReader(srcf, w)
	defer srcf.Close()
	dstf, err := os.Create(dstfile)
	if err != nil {
		log.Println("创建目标文件失败:", err)
		return err
	}
	defer dstf.Close()
	log.Println("开始拷贝:", dstfile)
	w.Bar.Start()
	_, err = io.Copy(dstf, r)
	if err != nil {
		return err
	}
	w.Bar.Finish()
	return nil
}

// 拷贝目录
func CopyDir(src, dst string) error {
	src = base.CleanPath(src)
	dst = base.CleanPath(dst)

	si, err := os.Stat(src)
	if err != nil {
		return err
	}
	if !si.IsDir() {
		return errors.New("source is not a directory")
	}

	if _, err := os.Stat(dst); err != nil {
		if os.IsNotExist(err) {
			err2 := os.MkdirAll(dst, si.Mode())
			if err2 != nil {
				return err2
			}
		} else {
			return err
		}
	}

	entries, err := ioutil.ReadDir(src)
	if err != nil {
		return err
	}

	for _, e := range entries {
		srcPath := filepath.Join(src, e.Name())
		dstPath := filepath.Join(dst, e.Name())

		if e.IsDir() {
			err = CopyDir(srcPath, dstPath)
			if err != nil {
				return err
			}
		} else {
			if e.Mode().IsRegular() {
				err = CopyFile(srcPath, dst)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}

func CheckWaitingPkgs() error {
	pkgs, err := WaitingPkgs()
	if err != nil {
		return err
	}
	for _, p := range pkgs {
		if !base.FileExists(p.Src) {
			return fmt.Errorf("订单包文件缺失: %s", base.JsonString(p))
		}
	}
	return nil
}
